using System;
using System.Collections;
using System.Collections.Generic;
using System.Drawing;
using System.Runtime.CompilerServices;
namespace Circus.Syntax.CodeCompletion
{
	public class CodeCompletionRepository : ICodeCompletionRepository
	{
		private bool caseSensitive;
		private SyntaxTree syntaxTree;
		private List<SyntaxTree> syntaxTrees;
		private Hashtable snippets;
		private Hashtable membersTable;
		private bool fillBaseMembers = true;
		private MemberLookupEventArgs memberLookupArgs;
		private DescriptionLookupEventArgs descriptionLookupArgs;
        public event MemberLookupEvent MemberLookup;
        public event DescriptionLookupEvent DescriptionLookup;
		public virtual Hashtable Snippets
		{
			get
			{
				return this.snippets;
			}
		}
		public virtual bool FillBaseMembers
		{
			get
			{
				return this.fillBaseMembers;
			}
			set
			{
				if (this.fillBaseMembers != value)
				{
					this.fillBaseMembers = value;
					this.OnFillBaseMembersChanged();
				}
			}
		}
		public virtual bool CaseSensitive
		{
			get
			{
				return this.caseSensitive;
			}
		}
		public virtual SyntaxTree SyntaxTree
		{
			get
			{
				return this.syntaxTree;
			}
		}
		public virtual IList<SyntaxTree> SyntaxTrees
		{
			get
			{
				return this.syntaxTrees;
			}
		}
		protected virtual object GetMemberKey(string name, int index)
		{
			return index.ToString() + "|" + name;
		}
		protected virtual bool CanAddMember(ListMembers members, MemberAttribute attributes, string name, int index, bool overloads)
		{
			bool result;
			if (name == string.Empty || (attributes & MemberAttribute.NoIntellisense) != MemberAttribute.None)
			{
				result = false;
			}
			else
			{
				if (this.ShouldDuplicate(members))
				{
					result = true;
				}
				else
				{
					object obj = this.membersTable[this.GetMemberKey(name, index)];
					if (obj != null && overloads)
					{
						((ListMember)obj).Overloads++;
					}
					result = (obj == null);
				}
			}
			return result;
		}
		protected virtual ListMember AddMember(ListMembers members, string name, int index)
		{
			ListMember listMember = members.AddListMember();
			listMember.Name = name;
			listMember.MemberType = index;
			listMember.ImageIndex = index;
			if (!this.ShouldDuplicate(members))
			{
				this.membersTable[this.GetMemberKey(name, index)] = listMember;
			}
			return listMember;
		}
		protected virtual void AddMember(ListMembers members, ListMember member)
		{
			((ListMembers)members).AddListMember(member);
			if (!this.ShouldDuplicate(members))
			{
				this.membersTable[this.GetMemberKey(member.Name, member.ImageIndex)] = member;
			}
		}
		protected virtual bool ShouldDuplicate(ListMembers members)
		{
			return members is ParameterInfo;
		}
		protected virtual void UpdateMethodParams(ListMember member, int paramIndex)
		{
			member.CurrentParamIndex = paramIndex;
		}
		protected virtual void UpdateMethodParams(ListMembers members, int paramIndex)
		{
			using (IEnumerator<IComparable> enumerator = members.GetEnumerator())
			{
				while (enumerator.MoveNext())
				{
					ListMember member = (ListMember)enumerator.Current;
					this.UpdateMethodParams(member, paramIndex);
				}
			}
		}
		protected virtual void UpdateMembersIndex(ListMembers members, int paramIndex)
		{
			for (int i = 0; i < members.Count; i++)
			{
				ListMember listMember = members[i];
				if (listMember.Parameters != null && paramIndex < listMember.Parameters.Count)
				{
					members.SelIndex = i;
					break;
				}
			}
		}
		protected virtual void DoFillMembers(SyntaxNode node, Point position, ListMembers members, IList<SyntaxNode> types, object member, string name, CodeCompletionScope scope, ref int selIndex)
		{
		}
		protected virtual object DoFindDeclaration(string text, SyntaxNode node, SyntaxNode refNode, Point position, int paramCount)
		{
			return null;
		}
		protected virtual void OnFillBaseMembersChanged()
		{
		}
		public CodeCompletionRepository(bool caseSensitive, SyntaxTree syntaxTree)
		{
			this.caseSensitive = caseSensitive;
			this.syntaxTree = syntaxTree;
			this.syntaxTrees = new List<SyntaxTree>();
			this.membersTable = new Hashtable();
			this.snippets = new Hashtable();
			this.memberLookupArgs = new MemberLookupEventArgs(null, string.Empty);
			this.descriptionLookupArgs = new DescriptionLookupEventArgs(null, string.Empty);
		}
		public virtual void FillMember(ListMembers members, object member, string name, CodeCompletionScope scope)
		{
		}
		public virtual object GetNodeType(string text, SyntaxNode node, Point position)
		{
			return this.DoFindDeclaration(text, node, node, position, 0);
		}
		public virtual object GetMemberType(string text, SyntaxNode node, ref string name, ref Point position, ref Point endPos, out CodeCompletionScope scope)
		{
			scope = CodeCompletionScope.None;
			return null;
		}
		public virtual object GetSpecialMemberType(string text, SyntaxNode node, ref string name, ref Point position, ref Point endPos, out CodeCompletionScope scope)
		{
			scope = CodeCompletionScope.None;
			return null;
		}
		public virtual object GetMethodType(string text, SyntaxNode node, ref string name, ref Point position, ref Point endPos, out int paramIndex, out int paramCount, out CodeCompletionScope scope)
		{
			paramIndex = -1;
			paramCount = 0;
			scope = CodeCompletionScope.None;
			return null;
		}
		public virtual void FillMembers(SyntaxNode node, Point position, ListMembers members, object member, string name, CodeCompletionScope scope, ref int selIndex)
		{
			this.membersTable.Clear();
			IList<SyntaxNode> types = new List<SyntaxNode>();
			this.DoFillMembers(node, position, members, types, member, name, scope, ref selIndex);
		}
		public virtual void FillMember(ListMembers members, object member, string name, int paramIndex, CodeCompletionScope scope)
		{
			this.membersTable.Clear();
			this.FillMember(members, member, name, scope);
			this.UpdateMethodParams(members, paramIndex);
			this.UpdateMembersIndex(members, paramIndex);
		}
		public virtual object GetMemberType(SyntaxNode node, Point position, object member, string name, out CodeCompletionScope scope)
		{
			object result;
			if (this.MemberLookup != null)
			{
				this.memberLookupArgs.Member = member;
				this.memberLookupArgs.Name = name;
				this.memberLookupArgs.Result = null;
				this.memberLookupArgs.Scope = CodeCompletionScope.None;
				this.MemberLookup(this, this.memberLookupArgs);
				if (this.memberLookupArgs.Result != null)
				{
					scope = this.memberLookupArgs.Scope;
					result = this.memberLookupArgs.Result;
					return result;
				}
			}
			scope = CodeCompletionScope.None;
			result = null;
			return result;
		}
		public virtual string GetDescription(ListMembers members, SyntaxNode node, object member, string name, bool fullDescription)
		{
			string result;
			if (this.DescriptionLookup != null)
			{
				this.descriptionLookupArgs.Member = member;
				this.descriptionLookupArgs.Name = name;
				this.descriptionLookupArgs.Description = string.Empty;
				this.DescriptionLookup(this, this.descriptionLookupArgs);
				result = this.descriptionLookupArgs.Description;
			}
			else
			{
				result = string.Empty;
			}
			return result;
		}
		public virtual int GetPriority(object member)
		{
			return 0;
		}
		public virtual object FindDeclaration(string text, SyntaxNode node, Point position)
		{
			return this.DoFindDeclaration(text, node, node, position, 0);
		}
		public virtual int FindReferences(SyntaxNode node, SyntaxNodes references)
		{
			references.Clear();
			references.Add(node);
			return 0;
		}
		public virtual void RegisterSyntaxTree(SyntaxTree tree)
		{
			this.syntaxTrees.Add(tree);
		}
		public virtual bool UnregisterSyntaxTree(SyntaxTree tree)
		{
			int num = this.syntaxTrees.IndexOf(tree);
			if (num >= 0)
			{
				this.syntaxTrees.RemoveAt(num);
			}
			return num >= 0;
		}
		public virtual void RegisterSnippet(string snippet, bool isStatement)
		{
			this.snippets.Add(snippet, isStatement);
		}
		public virtual bool UnregisterSnippet(string snippet)
		{
			bool result;
			if (this.snippets.Contains(snippet))
			{
				this.snippets.Remove(snippet);
				result = true;
			}
			else
			{
				result = false;
			}
			return result;
		}
		public virtual ICodeSnippetsProvider GetCodeSnippets(string language)
		{
			return null;
		}
	}
}
